package com.zijing2333.adaptivescheduling.SwitcherManager.client;


import android.util.Log;

import com.zijing2333.adaptivescheduling.ChannelManager;
import com.zijing2333.adaptivescheduling.SwitcherManager.TaskInfoManager;
import com.zijing2333.adaptivescheduling.SwitcherManager.flow.StringDataFlow;
import com.zijing2333.adaptivescheduling.criticalNodeJudgment.JudgeKeyNode;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * * 该类的一个的对象和某个服务器端保持通信，这个类主要是接收服务器端发来的数据----在run方法中   以及发送给服务器端数据-----在write开头的方法中
 */

public class ClientConnectServerThread implements Runnable {

    private static final String TAG = "fun_ClientConnectServerThread_time";
    private Socket mSocket; //主要用在客户端接收服务器端数据中
    private  ClientCallback mCallback;//主要用在客户端接收服务器端数据中

    protected DataInputStream mDis;//主要用在客户端接收服务器端数据中

    protected DataOutputStream mDos;//主要用在客户端发送数据给服务器端中

    private OutputStream outputStream;

    private InputStream inputStream;

    private boolean mIsRunning = false;//主要标志客户端和服务器端是否保持连接的状态

    private final int MIGRATION_DATA = 1; //携带服务的状态数据
    private final int NOTICE = 2; //通知  对端接收后还需要对是否是关键节点进行判断

    private final int MIGRATION_IP = 3; //携带源ip地址




    public ClientConnectServerThread(Socket socket,ClientCallback callback){
        this.mSocket = socket;
        this.mCallback = callback;
        try {
            inputStream = socket.getInputStream();
            mDis = new DataInputStream(inputStream);
            outputStream = socket.getOutputStream();
            mDos= new DataOutputStream(outputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    @Override
    public void run() {
        setRunning(true);
        while (mIsRunning){
            try {
                int dataType = mDis.readInt();
                String JsServiceId = mDis.readUTF();
                String data = mDis.readUTF();
                if (dataType == 1){ //B设备收到A设备发来的任务流转数据
                    Log.d(TAG, "B设备收到A设备发来的任务状态值："+data+",任务id为"+JsServiceId);
                    if (TaskInfoManager.getInstance().getJsMap().get(JsServiceId) != null ){ //说明是收到切换任务的部署通知
                        Log.d(TAG, "B设备收到A设备发来的任务状态值：--------分支1");
                        long timestamp1 = System.currentTimeMillis();
                        Log.d(TAG, "B设备收到A设备发来的任务状态数据（Socket）的时间:"+timestamp1);
                        mCallback.receiveServerMsg(1,JsServiceId,data,false); //这里用回调函数，让服务端设备上的任务进行状态的恢复操作
                    }else if (TaskInfoManager.getInstance().getCopyMap().get(JsServiceId) != null){ //说明是收到副本任务的部署通知
                        Log.d(TAG, "B设备收到A设备发来的任务状态值：--------分支2");
                        //调用mSwither的启动副本任务的方法（注意传入的参数不同）
                        mCallback.receiveServerMsg(1,JsServiceId,data,true);
                    }
                }else if (dataType == 2){ //B设备收到A设备发来的通知：进行副本的消除
                    TaskInfoManager.getInstance().removeCopyMap(JsServiceId);
                    //关闭socket客户端
                    ChannelManager.getInstance().stopClient(JsServiceId); //关闭副本任务与原任务建立的socket
                    //调用JS运行时的方法mSwitch，将Js运行时中的副本信息删除
                    mCallback.receiveServerMsg(2,JsServiceId,null,false);

                }else if (dataType == 3){ //对方发送过来的是源IP地址
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        close();
    }


    private void setRunning(boolean running) {
        mIsRunning = running;
    }
    private void stopRunning() {
        mIsRunning = false;
    }

    public boolean isRunning() {
        return mIsRunning;
    }

    /**
     * 送给数据给服务器端
     * @param data
     */
    public void writeString(String ServiceId, String type,String data) {
        try {
            if ("1".equals(type)){
                mDos.writeInt(MIGRATION_DATA); //这个是发送任务状态数据
                mDos.writeUTF(ServiceId);
                mDos.writeUTF(data);
                mDos.flush();
            }else if ("2".equals(type)){
                mDos.writeInt(NOTICE); //这个是发送通知
                mDos.writeUTF(ServiceId);
                mDos.flush();
            }else if ("3".equals(type)){
                long timestamp1 = System.currentTimeMillis();
                Log.d(TAG, "B设备给A设备发送（Socket）通知的时间:"+timestamp1);
                mDos.writeInt(MIGRATION_IP); //这个是发送源ip地址
                mDos.writeUTF(ServiceId);
                mDos.writeUTF(data);
                mDos.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    public void close() {
        Log.d(TAG, "客户端socket线程关闭========================");
        stopRunning();
        try {
            if (mDos != null){
                mDos.close();
            }
            if (outputStream !=null){
                outputStream.close();
            }
            if (mDis != null){
                mDis.close();
            }
            if (inputStream !=null){
                inputStream.close();
            }
            if (mSocket != null) {
                mSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



}
